home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’94 / [√] Distribution Restricted! / Brian Hamlin / Boom! / Boom.c < prev    next >
C/C++ Source or Header  |  1994-07-04  |  13KB  |  539 lines

  1. /*
  2.     Boom!  A quick Hack to Show off PPC graphics (68k version)
  3.  
  4.     @MacHack94     bh      noEsis Software Construction 
  5. */
  6.  
  7. //****************************************************************
  8. //                                                I N C L U D E S
  9.  
  10. #include <Types.h>
  11. #include <Memory.h>
  12. #include <A4Stuff.h>
  13. #include <SetUpA4.h>
  14. #include <Quickdraw.h>
  15. #include <QDOffscreen.h>
  16. #include <LowMem.h>
  17. #include <Errors.h>
  18. #include <GestaltEqu.h>
  19. #include <Resources.h>
  20. #include <Events.h>
  21. #include <Windows.h>
  22. #include <Sound.h>
  23.  
  24. #include <MixedMode.h>
  25.  
  26. #include <fp.h>
  27. #undef NAN
  28. #include <SANE.h>
  29.  
  30.  
  31. //****************************************************************
  32. //                                                C O N S T A N T S
  33. #define FALSE                false
  34. #define TRUE                true
  35. #define NIL                    0L
  36.  
  37.  
  38. //******************************
  39. //    The 68k code goes in a normal INIT resource.
  40. //    Be sure this is set to "system heap/locked".
  41.  
  42. #define kInitRezType        'INIT'
  43. #define kInitRezID            300
  44.  
  45. #define kMinSystemVersion    (0x0603)
  46.  
  47.  
  48.  
  49. //******************************
  50. // from Windows.h:
  51. // pascal Boolean TrackGoAway( WindowPtr theWindow, Point thePt)
  52. //   ONEWORDINLINE(0xA91E);
  53.  
  54. enum {
  55.  
  56.     kTrackGoAwayInfo = kCStackBased 
  57.                             | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) 
  58.                             | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))
  59.                             | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Point)))
  60. };
  61.  
  62.  
  63. typedef pascal Boolean ( *TrackGoAwayFuncPtr ) ( WindowPtr theWindow, Point thePt );
  64. typedef UniversalProcPtr UPP;
  65.  
  66.  
  67. // ShowInit 
  68. #define kOkOldMac    128
  69. #define kOkPPC        130
  70. #define kNotOldMac    132
  71. #define kNotPPC        134
  72.  
  73. // explosion constants
  74. struct exVector {
  75.     short            theta;        // 0-360
  76.     short            speed;        // small integer
  77.     Point            pPos;        // current position
  78.     Rect            pDispR;        // current drawn size of 'bit
  79.     GWorldPtr        tPixGwP;    // map  0,0,kSrcPixSiz,kSrcPixSiz
  80. };
  81. typedef struct exVector exVector;
  82.  
  83. #define kModBits 6
  84. #define kFrameCnt 20
  85. #define kModSpeed 12
  86. #define kSrcPixSiz {0,0,3,3}
  87. #define kScratchSize 265
  88.  
  89.  
  90. //****************************************************************
  91. //                                                G L O B A L S
  92.  
  93. struct NInitGlobals
  94. {
  95.     UPP                gOrigTrackGoAway;    // old Addr
  96.     SysEnvRec        gSystemInfo;
  97.     long            gInfo;        // 1=68k,2=PPC
  98.  
  99.     Handle            gSndHandle;
  100.     SndChannelPtr    gSndChP;
  101.     exVector        *gBits;
  102.     short             gNumBits;
  103.     short             gFrameCnt;
  104.     GWorldPtr        gPad;            // working image
  105.     GWorldPtr        gSavPad;        // pristine screen copy
  106. };
  107. typedef struct NInitGlobals NInitGlobals;
  108.  
  109. NInitGlobals                *gP;
  110.  
  111.  
  112. //****************************************************************
  113. //                                                F O R W A R D S
  114.  
  115. pascal Boolean nTrackGoAway68k( WindowPtr theWindow, Point thePt);
  116. OSErr DoInitForOldMacs( void);
  117.  
  118. void PlayBoom(void);
  119. OSErr SetUpSim(void);
  120. void Animate(Point cPt);
  121. void AnimateDone(void);
  122. void ImageFrame(short frameNum, GWorldPtr dstGW, Point exPt);
  123. void PlotImage( GWorldPtr gw, short theta, short speed);
  124.  
  125. extern void ShowIconFamily(short iconId);
  126.  
  127.  
  128. //****************************************************************
  129. void main( void )
  130. {
  131.     long        oldA4, lRes;
  132.     Handle        initH = nil;        /* Handle to our own INIT resource */
  133.     OSErr        err = noErr;
  134.     
  135.     oldA4 = SetCurrentA4();            /* Get the proper value of A4 into A4 */
  136.     RememberA4();                    /* save into self-modifying code */
  137.  
  138.  
  139.     // Allocate globals struct
  140.     gP = (NInitGlobals*) NewPtrSysClear( sizeof(NInitGlobals));
  141.     if ( !gP ) {
  142.         err = memFullErr;
  143.         goto DONE;
  144.     }
  145.     
  146.      // Get minimal System Info:
  147.     err = SysEnvirons( 1, &gP->gSystemInfo );
  148.     if ( err )
  149.         goto DONE;
  150.       if ( gP->gSystemInfo.systemVersion < kMinSystemVersion ) {
  151.          err = -1;
  152.          goto DONE;
  153.      }
  154.  
  155.     // Prepare to Detach ourselves...
  156.     initH = Get1Resource( kInitRezType, kInitRezID );
  157.     if ( !initH ) {
  158.         err = resNotFound;
  159.         goto DONE;
  160.     }
  161.  
  162.     // Call Gestalt:
  163.     // Gestalt will return an err when SysArc is unimplemented
  164.     err = Gestalt( gestaltSysArchitecture, &gP->gInfo );
  165.     if ( err) gP->gInfo = gestalt68k;
  166.  
  167.     // Load 'snd ':
  168.     // this snd is marked 'sysHeap', so it'll land in the right place,
  169.     // and we have to detach anything we want to keep around
  170.     gP->gSndHandle = GetResource ('snd ', 128);
  171.     DetachResource( gP->gSndHandle);
  172.     
  173.     { // Make a new SndChannel in the System Heap
  174.     THz savZone = GetZone();
  175.     SetZone( SystemZone());
  176.     err = SndNewChannel( &gP->gSndChP, sampledSynth, initMono, 0);
  177.     if ( err != noErr) goto DONE;
  178.     SetZone( savZone);
  179.     }
  180.     
  181.     err = DoInitForOldMacs();    // sorry, 68k setup only
  182.  
  183.  
  184.     DONE:
  185.     if ( err ) {
  186.         ShowIconFamily((gP->gInfo==gestalt68k)?(kNotOldMac):(kNotPPC));
  187.         if ( gP )
  188.             DisposPtr( (Ptr)gP );
  189.     } else {
  190.         ShowIconFamily((gP->gInfo==gestalt68k)?(kOkOldMac):(kOkPPC));
  191.         DetachResource( initH);    
  192.         MoveHHi( (Handle)initH); HLock( (Handle)initH);
  193.     }
  194.     
  195.     RestoreA4( oldA4 );                    /* restore previous value of A4 */
  196. }
  197.  
  198.  
  199.  
  200. //****************************************************************
  201. //    DoInitForOldMacs
  202. //****************************************************************
  203. OSErr DoInitForOldMacs( void )
  204. {
  205.     long    oldA4;
  206.     NInitGlobals *locGPtr;
  207.  
  208.     oldA4 = SetUpA4();    
  209.     locGPtr = gP;
  210.     RestoreA4( oldA4 );    
  211.  
  212.     locGPtr->gOrigTrackGoAway = NGetTrapAddress( _TrackGoAway, ToolTrap );
  213.     NSetTrapAddress( (UPP)nTrackGoAway68k, _TrackGoAway, ToolTrap );
  214.     
  215.     return noErr;
  216. }
  217.  
  218.  
  219. //****************************************************************
  220. pascal Boolean nTrackGoAway68k( WindowPtr theWindow, Point thePt )
  221. {
  222.     Boolean        res;
  223.     long        oldA4;
  224.     GrafPtr        tPort;
  225.     Point        savPt;
  226.     TrackGoAwayFuncPtr ptr;
  227.     NInitGlobals *locGPtr;
  228.  
  229.     oldA4 = SetUpA4();        
  230.     locGPtr = gP;
  231.     
  232.     ptr = (TrackGoAwayFuncPtr)locGPtr->gOrigTrackGoAway;
  233.     savPt = thePt;
  234.     res = ( *ptr )( theWindow, thePt );
  235.     
  236.     if ( res == true) { 
  237.  
  238.         if ( locGPtr->gInfo == gestaltPowerPC || *(short*)0x17A) {
  239.             THz savZone = GetZone();
  240.             SetZone( SystemZone());
  241.             
  242.             if ( SetUpSim() == noErr) {
  243.                 HideCursor();
  244.                 Animate( savPt);
  245.                 AnimateDone();
  246.                 ShowCursor();
  247.             }
  248.             SetZone( savZone);
  249.         }    
  250.     }
  251.  
  252.     RestoreA4( oldA4 );    
  253.     return res;
  254.  
  255.  
  256. //***********************************************************
  257. void AnimateDone()
  258. {
  259.     short cnt;
  260.  
  261.     DisposeGWorld( gP->gPad);
  262.     DisposeGWorld( gP->gSavPad);
  263.     for ( cnt=0;cnt<gP->gNumBits; cnt++)
  264.         DisposeGWorld( gP->gBits[cnt].tPixGwP);
  265.  
  266.     DisposPtr( (Ptr)gP->gBits);
  267. }
  268.  
  269.  
  270. //***********************
  271. #define abs(x) ((x>0)?(x):(-x))
  272.  
  273. OSErr SetUpSim(void)
  274. {
  275.     short cnt, prevT;
  276.     Rect r = kSrcPixSiz;
  277.     Rect r2;
  278.     OSErr err;
  279.  
  280.     // init scratch pads
  281.     SetRect( &r2, 0, 0, kScratchSize, kScratchSize);
  282.     err = NewGWorld( &gP->gPad,8,&r2,0,0,0);    // 8 bits only, sorry
  283.     if ( err != noErr) return err;
  284.     err = NewGWorld( &gP->gSavPad,8,&r2,0,0,0);    // 8 bits only, sorry
  285.     if ( err != noErr) return err;
  286.  
  287.     // allocate 'bits array
  288.     gP->gNumBits = abs(TickCount() % kModBits) + 5;    //ok, max+n
  289.  
  290.     gP->gBits = (exVector*)NewPtrClear( gP->gNumBits*sizeof(exVector));
  291.     for ( cnt=0;cnt<gP->gNumBits; cnt++){
  292.         gP->gBits[cnt].theta = abs((TickCount()*10+cnt) % 360);
  293.         gP->gBits[cnt].speed = abs(TickCount() % kModSpeed) + 4;
  294.         gP->gBits[cnt].pPos.h = 0;
  295.         gP->gBits[cnt].pPos.v = 0;
  296.         gP->gBits[cnt].pDispR = r;
  297.  
  298.         err = NewGWorld( &gP->gBits[cnt].tPixGwP,
  299.                     8,&r,0,0,0);
  300.         if ( err != noErr) return err;
  301.  
  302.         // now, based on speed and theta, make an image
  303.         PlotImage( gP->gBits[cnt].tPixGwP, gP->gBits[cnt].theta, gP->gBits[cnt].speed);
  304.     }
  305.     return err;
  306. }
  307.  
  308.  
  309. //**************************************************************
  310. //
  311. //    Order of Events: 
  312. //    Prestine PixMap is in gP->gSavPad, working PixMap is in gP->gPad
  313. //    For each cell of animation, copy the savPad to workPad,
  314. //    Draw all 'bits for this frame, copy gP->gPad to the screen.
  315. //    
  316.                 
  317. void Animate( Point cPt)
  318. {
  319.     GrafPtr savP; GrafPort dPort;
  320.     Rect wR; long t;
  321.     short offX=0;
  322.     short offY=0;
  323.     Point    exPt;
  324.  
  325.     PlayBoom();
  326.  
  327.     GetPort( &savP);
  328.     OpenPort( &dPort);
  329.     SetPort( &dPort);
  330.  
  331.     wR = gP->gPad->portRect;    
  332.  
  333.     // if the point is closer to the side of the screen than
  334.     // half the width of our buffered draw area, then adjust
  335.     // the explosion center
  336.  
  337.     if ( cPt.h > wR.right/2) {
  338.         offX = cPt.h - wR.right/2;
  339.         exPt.h = wR.right/2;
  340.     } else exPt.h = cPt.h;
  341.     if ( cPt.v > wR.bottom/2) {
  342.         offY = cPt.v - wR.bottom/2;
  343.         exPt.v = wR.bottom/2;
  344.     } else exPt.v = cPt.v;
  345.     OffsetRect( &wR, offX, offY);
  346.  
  347.     // init savMap 
  348.     CopyBits(    (BitMap*)(&(dPort.portBits)),
  349.                 (BitMap*)(*(gP->gSavPad->portPixMap)), 
  350.                 &wR, &gP->gPad->portRect,
  351.                 patCopy, 0);
  352.                 
  353.     // special effects
  354.     {
  355.         #define kMax 6
  356.         Rect tR, exR; short cnt;
  357.         RGBColor tC = {0x0000,0x0000,0x0000};
  358.         PenMode( blend);    ForeColor( whiteColor);
  359.         exR.left = cPt.h - kScratchSize/2;
  360.         exR.right = cPt.h + kScratchSize/2;
  361.         exR.top = cPt.v - kScratchSize/2;
  362.         exR.bottom = cPt.v + kScratchSize/2;
  363.         for ( cnt=1; cnt<=kMax; cnt++){
  364.             tR = exR;
  365.             tC.red += 0x2A00; tC.green += 0x2A00; tC.blue += 0x2A00;
  366.             OpColor( &tC);
  367.             InsetRect( &tR, cnt*(kScratchSize/kMax), cnt*(kScratchSize/kMax));
  368.             PaintOval( &tR);
  369.             if ( gP->gInfo == gestaltPowerPC)
  370.                 Delay( 1, &t);
  371.         }
  372.         PenNormal();    ForeColor( blackColor);
  373.         if ( gP->gInfo == gestaltPowerPC)
  374.             Delay( 2, &t);
  375.         #undef kMax
  376.     }
  377.  
  378.     // animate
  379.     for (gP->gFrameCnt=0;gP->gFrameCnt<kFrameCnt;gP->gFrameCnt++) {
  380.         // copy savPad to workPad
  381.         CopyBits(    (BitMap*)(*(gP->gSavPad->portPixMap)), 
  382.                     (BitMap*)(*(gP->gPad->portPixMap)),
  383.                     &gP->gSavPad->portRect, &gP->gPad->portRect,
  384.                     patCopy, 0);
  385.  
  386.         ImageFrame(gP->gFrameCnt, gP->gPad, exPt);    // image 'bits
  387.  
  388.         // copy workPad to screen
  389.         CopyBits(    (BitMap*)(*(gP->gPad->portPixMap)), 
  390.                     (BitMap*)(&(dPort.portBits)),
  391.                     &gP->gPad->portRect, &wR,
  392.                     patCopy, 0);
  393.  
  394.         if ( gP->gInfo == gestaltPowerPC)
  395.             Delay( gP->gFrameCnt/4, &t);
  396.     }
  397.  
  398.     // restore screen
  399.     CopyBits(    (BitMap*)(*(gP->gSavPad->portPixMap)),
  400.                 (BitMap*)(&(dPort.portBits)), 
  401.                 &gP->gPad->portRect, &wR,
  402.                 patCopy, 0);
  403.  
  404.     SetPort( savP);
  405.     ClosePort( &dPort);
  406.     
  407.     return;
  408. }
  409.  
  410. //***********************************
  411. void ImageFrame( short frameNum, GWorldPtr dstGW, Point exPt) 
  412. {
  413.     short    posX, posY;
  414.     short    cnt, f, tSpd;
  415.     long    t;
  416.     Rect    srcR = kSrcPixSiz;
  417.     Rect    dstR;
  418.  
  419.     // r is frameCnt * speed+frameCnt
  420.     // posX = r*cos(t)
  421.     // posY = r*sin(t)
  422.     
  423.     for (f=frameNum,cnt=0;cnt<gP->gNumBits;cnt++) {
  424.         tSpd = gP->gBits[cnt].speed;
  425.         posX = (short)(f*(tSpd+cnt)) * cos(gP->gBits[cnt].theta);
  426.         posY = (short)(f*(tSpd+cnt)) * sin(gP->gBits[cnt].theta);
  427.  
  428.         dstR = gP->gBits[cnt].pDispR;
  429.  
  430.         dstR.left += exPt.h+posX;
  431.         dstR.right += exPt.h+posX;
  432.         dstR.top += exPt.v+posY;
  433.         dstR.bottom += exPt.v+posY;
  434.  
  435.         CopyBits(    (BitMap*)(*(gP->gBits[cnt].tPixGwP->portPixMap)), 
  436.                     (BitMap*)(*(dstGW->portPixMap)),
  437.                     &srcR, &dstR,
  438.                     patCopy, 0);
  439.     }
  440. }
  441.  
  442. //**********************
  443. // Create one explosion 'bit
  444. void PlotImage( GWorldPtr gw, short theta, short speed)
  445. {
  446.     GWorldPtr     savGW;
  447.     GDHandle      savGdH;
  448.     Rect        r = kSrcPixSiz;
  449.     Point        pR1a, pR1b, pR1c;
  450.     Point        pR2, pO1, pY1a, pY1b;
  451.     RGBColor    c;
  452.  
  453.     GetGWorld( &savGW, &savGdH);
  454.     SetGWorld( gw, 0);
  455.  
  456.     c.red = 0xFFFF; c.green = 0xFFFF; c.blue = 0xFFFF;
  457.     RGBForeColor( &c);
  458.     PaintRect( &r);
  459.     PenNormal();
  460.  
  461.     if ( theta <= 22) {                                                // 22
  462.         pR1a.h=1; pR1a.v=2; pR1b.h=2; pR1b.v=1; pR1c.h=1; pR1c.v=0;
  463.         pR2.h=2; pR2.v=0; pO1.h=2; pO1.v=2; 
  464.         pY1a.h=0; pY1a.v=2; pY1b.h=0; pY1b.v=0;
  465.     } else if ( theta <= 77)  {                                        // 77
  466.         pR1a.h=2; pR1a.v=2; pR1b.h=2; pR1b.v=0; pR1c.h=0; pR1c.v=0;
  467.         pR2.h=1; pR2.v=0; pO1.h=2; pO1.v=1; 
  468.         pY1a.h=1; pY1a.v=2; pY1b.h=0; pY1b.v=1;
  469.     } else if ( theta <= 112)  {                                    // 112
  470.         pR1a.h=2; pR1a.v=1; pR1b.h=1; pR1b.v=0; pR1c.h=0; pR1c.v=1;
  471.         pR2.h=0; pR2.v=0; pO1.h=2; pO1.v=0; 
  472.         pY1a.h=2; pY1a.v=2; pY1b.h=0; pY1b.v=2;
  473.     } else if ( theta <= 157)  {                                    // 157
  474.         pR1a.h=2; pR1a.v=0; pR1b.h=0; pR1b.v=0; pR1c.h=0; pR1c.v=2;
  475.         pR2.h=0; pR2.v=1; pO1.h=1; pO1.v=0; 
  476.         pY1a.h=2; pY1a.v=1; pY1b.h=1; pY1b.v=2;
  477.     } else if ( theta <= 202)  {                                    // 202
  478.         pR1a.h=1; pR1a.v=0; pR1b.h=0; pR1b.v=1; pR1c.h=1; pR1c.v=2;
  479.         pR2.h=0; pR2.v=2; pO1.h=0; pO1.v=0; 
  480.         pY1a.h=2; pY1a.v=0; pY1b.h=2; pY1b.v=2;
  481.     } else if ( theta <= 247)  {                                    // 247
  482.         pR1a.h=0; pR1a.v=0; pR1b.h=0; pR1b.v=2; pR1c.h=2; pR1c.v=2;
  483.         pR2.h=1; pR2.v=2; pO1.h=0; pO1.v=1; 
  484.         pY1a.h=1; pY1a.v=0; pY1b.h=2; pY1b.v=1;
  485.     } else if ( theta <= 292)  {                                    // 292
  486.         pR1a.h=0; pR1a.v=1; pR1b.h=1; pR1b.v=2; pR1c.h=2; pR1c.v=1;
  487.         pR2.h=2; pR2.v=2; pO1.h=0; pO1.v=2; 
  488.         pY1a.h=0; pY1a.v=0; pY1b.h=2; pY1b.v=0;
  489.     } else if ( theta <= 337)  {                                    // 337
  490.         pR1a.h=0; pR1a.v=2; pR1b.h=2; pR1b.v=2; pR1c.h=2; pR1c.v=0;
  491.         pR2.h=2; pR2.v=1; pO1.h=1; pO1.v=2; 
  492.         pY1a.h=0; pY1a.v=1; pY1b.h=1; pY1b.v=0;
  493.     } else {                                                        // +-22
  494.         pR1a.h=1; pR1a.v=2; pR1b.h=2; pR1b.v=1; pR1c.h=1; pR1c.v=0;
  495.         pR2.h=2; pR2.v=0; pO1.h=2; pO1.v=2; 
  496.         pY1a.h=0; pY1a.v=2; pY1b.h=0; pY1b.v=0;
  497.     }
  498.  
  499.     // NOTE: assumes 'bit pix size of 3x3 !!
  500.  
  501.     c.red = 0xFFFF; c.green = 0x2000; c.blue = 0;        // r1
  502.     RGBForeColor( &c);
  503.     MoveTo( pR1a.h,pR1a.v);    Line(0,0);
  504.     MoveTo( pR1b.h,pR1c.v);    Line(0,0);
  505.     MoveTo( pR1c.h,pR1c.v);    Line(0,0);
  506.  
  507.     c.red = 0xBAC7; c.green = 0; c.blue = 0;            // r2
  508.     RGBForeColor( &c);
  509.     MoveTo( pR2.h,pR2.v);    Line(0,0);
  510.     MoveTo( pO1.h,pO1.v);    Line(0,0);
  511.  
  512.     c.red = 0xFFFF; c.green = 0xCCC8; c.blue = 0;        // o2 (always center)
  513.     RGBForeColor( &c);
  514.     MoveTo( 1,1);    Line(0,0);
  515.  
  516.     c.red = 0xFFFF; c.green = 0xFFFF; c.blue = 0;        // y
  517.     RGBForeColor( &c);
  518.     MoveTo( pY1a.h,pY1a.v);    Line(0,0);
  519.     MoveTo( pY1b.h,pY1b.v);    Line(0,0);
  520.  
  521.     SetGWorld( savGW, savGdH);
  522.     return;
  523. }
  524.  
  525.  
  526. //***********************************************************
  527. void PlayBoom()
  528. {
  529.     OSErr err;
  530.  
  531.     if ( gP->gSndHandle != nil ) 
  532.         err = SndPlay( gP->gSndChP, gP->gSndHandle, true);
  533. }
  534.  
  535.  
  536. //***********************************************************************************
  537. //                                                        E N D   O F   L I S T I N G
  538.